package com.geekydoo.commands;

import generated.TaskType;

import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

import com.geekydoo.InputOutputHandler;
import com.geekydoo.InputValidation;
import com.rits.cloning.Cloner;

/**
 * The purpose of this class is to support deleting a task from the task list.
 * 
 * @author Wai Yau
 */
public class DeleteCommand implements Command {

	private static Logger logger = Logger.getLogger("geekydoo");

	// The list of all task objects managed by the program
	private List<TaskType> taskList;

	// List of all tasks as it was before a task was deleted
	private static List<TaskType> preExecutionList;

	// Indicates whether or not a task was deleted
	private boolean deleteExecuted = false;

	// Valid user input strings
	private static final String INPUT_YES = "((?i)yes)|((?i)y)";
	private static final String INPUT_NO = "((?i)no)|((?i)n)";

	// Prompts printed by the delete command
	private static final String PROMPT_ID = "Task ID: ";
	private static final String PROMPT_SURE = "Are you sure? (y/n): ";

	// Information messages
	private static final String INFO_NOT_DELETE = "You have decided not to delete a task.";
	private static final String INFO_EMPTY_LIST = "Task list is empty.";

	// Error messages
	private static final String ERROR_INVALID_ID = "Invalid task id.";

	public void execute(List<TaskType> tasks) {
		taskList = tasks;
		Cloner cloner = new Cloner();
		preExecutionList = cloner.deepClone(taskList);

		if (taskList.size() == 0) {
			logger.info("Task list is empty so can't delete anything");
			InputOutputHandler.printToConsole(INFO_EMPTY_LIST, true, false);
			return;
		}

		String id = InputOutputHandler.getInputFromConsole(PROMPT_ID, true);
		if (InputValidation.isValidId(id, taskList)) {
			String answer = InputOutputHandler.getInputFromConsole(PROMPT_SURE, true);
			while (!InputValidation.isValidYesNoResponse(answer)) {
				answer = InputOutputHandler.getInputFromConsole(PROMPT_SURE, true);
			}
			processResponse(answer, id);
		}
		else {
			InputOutputHandler.printToConsole(ERROR_INVALID_ID, true, false);
		}
	}

	/**
	 * This method deletes the task with the user specified id if the answer
	 * argument is 'y'. It does not delete the task if the answer argument is
	 * 'n'.
	 * 
	 * @param answer User input, which should be 'y' or 'n'
	 * @param id The task id of the task to be deleted
	 */
	private void processResponse(String answer, String id) {
		if (answer.matches(INPUT_YES)) {
			int oldSize = taskList.size();
			deleteTaskWithId(id);
			deleteExecuted = true;
			logger.info("Task with ID " + id + " was deleted");
			assert (taskList.size() == oldSize - 1);
		}
		else if (answer.matches(INPUT_NO)) {
			logger.info("User chose not to delete a task");
			InputOutputHandler.printToConsole(INFO_NOT_DELETE, true, false);
		}
	}

	/**
	 * This method deletes the task with id matching the id argument from the
	 * task list.
	 * 
	 * @param id The id of the task to delete from the list
	 */
	private void deleteTaskWithId(String id) {
		Iterator<TaskType> taskListIterator = taskList.iterator();
		while (taskListIterator.hasNext()) {
			TaskType task = taskListIterator.next();
			if (task.getId().equals(id)) {
				taskList.remove(task);
				InputOutputHandler.printToConsole("Task " + id + " has been removed from task list.", true, false);
				break;
			}
		}
	}

	public boolean isListModified() {
		return deleteExecuted;
	}

	public List<TaskType> getPreExecutionList() {
		return preExecutionList;
	}

}
